/****************************************************************************
 * Copyright (c) 2016 - 2018 Qualcomm Technologies International, Ltd.
****************************************************************************/
/**
 * \file hal_audio_common.h
 * \ingroup HAL
 *
 * Calculate the value of some preprocessor constants based on values
 * provided by the build system. It performs some sanity checks and
 * stop compilation if an error is detected.
 */
#ifndef HAL_AUDIO_COMMON_H
#define HAL_AUDIO_COMMON_H

#ifdef INSTALL_AUDIO_INTERFACE_PCM
#ifndef NUMBER_PCM_INSTANCES
#error "Number of PCM instances is not specified"
#endif
#ifdef CHIP_SUPPORTS_8CH_PCM
#define NUMBER_PCM_CHANNELS 8
#else
#define NUMBER_PCM_CHANNELS 4
#endif
#endif /* INSTALL_AUDIO_INTERFACE_PCM */

#ifdef INSTALL_AUDIO_INTERFACE_I2S
#ifndef NUMBER_I2S_INSTANCES
#error "Number of I2S instances is not specified"
#endif
#define NUMBER_I2S_CHANNELS 2
#endif /* INSTALL_AUDIO_INTERFACE_I2S */

#ifdef INSTALL_AUDIO_INTERFACE_SPDIF
#ifndef NUMBER_SPDIF_INSTANCES
#error "Number of SPDIF instances is not specified"
#endif
/* (does not include USER / A_AND_B_INTERLEAVED) */
#define NUMBER_SPDIF_CHANNELS 2
#endif /* INSTALL_AUDIO_INTERFACE_SPDIF */

#if defined(INSTALL_AUDIO_INTERFACE_PCM) || defined(INSTALL_AUDIO_INTERFACE_I2S)
#define NUMBER_DIGITAL_INTERFACES NUMBER_PCM_INSTANCES
#else
#define NUMBER_DIGITAL_INTERFACES 0
#endif /* INSTALL_AUDIO_INTERFACE_PCM */

#ifdef INSTALL_CODEC
#ifdef NUMBER_CODEC_INSTANCES
#define NUMBER_ADC_INSTANCES NUMBER_CODEC_INSTANCES
#define NUMBER_DAC_INSTANCES NUMBER_CODEC_INSTANCES
#elif (defined(NUMBER_ADC_INSTANCES) && defined(NUMBER_DAC_INSTANCES))
#else
#error "Number of CODEC instances is not specified"
#endif /* NUMBER_CODEC_INSTANCES */
#define NUMBER_CODEC_CHANNELS_PER_INSTANCE 2
#define NUMBER_ADC_CHANNELS_TOTAL (NUMBER_CODEC_CHANNELS_PER_INSTANCE * NUMBER_ADC_INSTANCES)
#define NUMBER_DAC_CHANNELS_TOTAL (NUMBER_CODEC_CHANNELS_PER_INSTANCE * NUMBER_DAC_INSTANCES)
#endif /* INSTALL_CODEC */

#ifdef INSTALL_DIGITAL_MIC
#ifdef NUMBER_DIGITAL_MICS
#if (NUMBER_DIGITAL_MICS % 2 != 0)
#define NUMBER_DM_INSTANCES ((NUMBER_DIGITAL_MICS + 1) / 2)
    #ifdef NUMBER_SIDETONES
    #define NUMBER_SIDETONE_SOURCE_INSTANCES ((NUMBER_SIDETONES + 1) / 2)
    #else
    #define NUMBER_SIDETONE_SOURCE_INSTANCES NUMBER_DM_INSTANCES
    #endif/*NUMBER_SIDETONES*/
#define NUMBER_DM_CHANNELS 2
#else
#define NUMBER_DM_INSTANCES (NUMBER_DIGITAL_MICS / 2)
    #ifdef NUMBER_SIDETONES
    #define NUMBER_SIDETONE_SOURCE_INSTANCES 4
    #else
    #define NUMBER_SIDETONE_SOURCE_INSTANCES NUMBER_DM_INSTANCES
    #endif /*NUMBER_SIDETONES*/
#define NUMBER_DM_CHANNELS 2
#endif /* (NUMBER_DIGITAL_MICS % 2 != 0) */
#else
#error NUMBER_DIGITAL_MICS must be defined
#endif /* NUMBER_DIGITAL_MICS */
#else
#define NUMBER_DM_CHANNELS 0
#endif /* INSTALL_DIGITAL_MIC */

#ifdef INSTALL_AUDIO_INTERFACE_PWM
#ifdef NUMBER_AUDIO_PWMS
#if (NUMBER_AUDIO_PWMS % 2 != 0)
#define NUMBER_PWM_INSTANCES ((NUMBER_AUDIO_PWMS + 1) / 2)
#define NUMBER_PWM_CHANNELS 2
#else
#define NUMBER_PWM_INSTANCES (NUMBER_AUDIO_PWMS / 2)
#define NUMBER_PWM_CHANNELS 2
#endif /* (NUMBER_AUDIO_PWMS % 2 != 0) */
#else
#error NUMBER_AUDIO_PWMS must be defined.
#endif /* NUMBER_AUDIO_PWMS */
#endif /* INSTALL_AUDIO_INTERFACE_PWM */

#if defined(NUMBER_ADC_CHANNELS_TOTAL) && defined(NUMBER_DIGITAL_MICS)
#if (NUMBER_DIGITAL_MICS >= NUMBER_ADC_CHANNELS_TOTAL)
#define NUMBER_KCODEC_ADC_CHANNELS_TOTAL    NUMBER_DIGITAL_MICS
#else
#define NUMBER_KCODEC_ADC_CHANNELS_TOTAL    NUMBER_ADC_CHANNELS_TOTAL
#endif /* NUMBER_DIGITAL_MICS >= NUMBER_ADC_CHANNELS_TOTAL */
#elif defined(NUMBER_ADC_CHANNELS_TOTAL) && !defined(NUMBER_DIGITAL_MICS)
#define NUMBER_KCODEC_ADC_CHANNELS_TOTAL    NUMBER_ADC_CHANNELS_TOTAL
#elif !defined(NUMBER_ADC_CHANNELS_TOTAL) && defined(NUMBER_DIGITAL_MICS)
#define NUMBER_KCODEC_ADC_CHANNELS_TOTAL    NUMBER_DIGITAL_MICS
#endif

/*SIDETONE path uses decimation chain as input and maor
** has lesser sidetone than decimation chains i.e. some 
** decimation chain does not support SIDETONE. */
#if NUMBER_KCODEC_ADC_CHANNELS_TOTAL>8
#define NUMBER_SIDETONE_ADC_CHANNELS_TOTAL 8 
#else
#define NUMBER_SIDETONE_ADC_CHANNELS_TOTAL NUMBER_KCODEC_ADC_CHANNELS_TOTAL
#endif 

#if defined NUMBER_KCODEC_ADC_CHANNELS_TOTAL
#if (NUMBER_KCODEC_ADC_CHANNELS_TOTAL % 2 != 0)
#define NUMBER_KCODEC_ADC_INSTANCES ((NUMBER_KCODEC_ADC_CHANNELS_TOTAL + 1) / 2);
#else
#define NUMBER_KCODEC_ADC_INSTANCES (NUMBER_KCODEC_ADC_CHANNELS_TOTAL / 2);
#endif /* (NUMBER_KCODEC_ADC_CHANNELS_TOTAL % 2 != 0) */
#endif /* NUMBER_KCODEC_ADC_CHANNELS_TOTAL */

#if defined(NUMBER_DAC_CHANNELS_TOTAL) && defined(NUMBER_AUDIO_PWMS)
#if (NUMBER_AUDIO_PWMS >= NUMBER_DAC_CHANNELS_TOTAL)
#define NUMBER_KCODEC_DAC_CHANNELS_TOTAL    NUMBER_AUDIO_PWMS
#else
#define NUMBER_KCODEC_DAC_CHANNELS_TOTAL    NUMBER_DAC_CHANNELS_TOTAL
#endif /* NUMBER_AUDIO_PWMS >= NUMBER_DAC_CHANNELS_TOTAL */
#elif defined(NUMBER_DAC_CHANNELS_TOTAL) && !defined(NUMBER_AUDIO_PWMS)
#define NUMBER_KCODEC_DAC_CHANNELS_TOTAL    NUMBER_DAC_CHANNELS_TOTAL
#elif !defined(NUMBER_DAC_CHANNELS_TOTAL) && defined(NUMBER_AUDIO_PWMS)
#define NUMBER_KCODEC_DAC_CHANNELS_TOTAL    NUMBER_AUDIO_PWMS
#endif

#if defined NUMBER_KCODEC_DAC_CHANNELS_TOTAL
#if (NUMBER_KCODEC_DAC_CHANNELS_TOTAL % 2 != 0)
#define NUMBER_KCODEC_DAC_INSTANCES ((NUMBER_KCODEC_DAC_CHANNELS_TOTAL + 1) / 2);
#else
#define NUMBER_KCODEC_DAC_INSTANCES (NUMBER_KCODEC_DAC_CHANNELS_TOTAL / 2);
#endif /* (NUMBER_KCODEC_DAC_CHANNELS_TOTAL % 2 != 0) */
#endif /* NUMBER_KCODEC_DAC_CHANNELS_TOTAL */

#if defined(NUMBER_KCODEC_DAC_CHANNELS_TOTAL) && defined(NUMBER_KCODEC_ADC_CHANNELS_TOTAL)
#if (NUMBER_KCODEC_DAC_CHANNELS_TOTAL >= NUMBER_KCODEC_ADC_CHANNELS_TOTAL)
#define NUMBER_KCODEC_CHANNELS_TOTAL NUMBER_KCODEC_DAC_CHANNELS_TOTAL
#else
#define NUMBER_KCODEC_CHANNELS_TOTAL NUMBER_KCODEC_ADC_CHANNELS_TOTAL
#endif /* (NUMBER_KCODEC_DAC_CHANNELS_TOTAL >= NUMBER_KCODEC_ADC_CHANNELS_TOTAL) */
#elif ! defined(NUMBER_KCODEC_DAC_CHANNELS_TOTAL) && defined(NUMBER_KCODEC_ADC_CHANNELS_TOTAL)
#define NUMBER_KCODEC_CHANNELS_TOTAL NUMBER_KCODEC_ADC_CHANNELS_TOTAL
#elif defined(NUMBER_KCODEC_DAC_CHANNELS_TOTAL) && ! defined(NUMBER_KCODEC_ADC_CHANNELS_TOTAL)
#define NUMBER_KCODEC_CHANNELS_TOTAL NUMBER_KCODEC_DAC_CHANNELS_TOTAL
#endif

#if defined NUMBER_KCODEC_CHANNELS_TOTAL
#define NUMBER_KCODEC_CHANNELS_PER_INSTANCE 2
#if (NUMBER_KCODEC_CHANNELS_TOTAL % NUMBER_KCODEC_CHANNELS_PER_INSTANCE != 0)
#define NUMBER_KCODEC_INSTANCES ((NUMBER_KCODEC_CHANNELS_TOTAL + 1) / NUMBER_KCODEC_CHANNELS_PER_INSTANCE);
#else
#define NUMBER_KCODEC_INSTANCES (NUMBER_KCODEC_CHANNELS_TOTAL / NUMBER_KCODEC_CHANNELS_PER_INSTANCE);
#endif /* (NUMBER_KCODEC_CHANNELS_TOTAL % 2 != 0) */
#endif /* NUMBER_KCODEC_CHANNELS_TOTAL */

#endif /* HAL_AUDIO_COMMON_H */
